package com.example.my_self_view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.util.TypedValue
import android.view.MotionEvent
import android.view.View


class MyTextView: View {

    private var mText: String? = null
    private var mTextSize = 15 // 15px
    private var mTextColor = Color.BLACK
    private var mPaint: Paint
    private val mRect = Rect()

    // 构造函数会在代码里面new的时候调用
    // val textView = TextView(context)
    constructor(context: Context): this(context, null) {
    }

    // 在布局layout中使用
    constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0) {

    }

    // 在布局layout中使用，但是同时设置了style
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(context, attrs, defStyleAttr, 0) {

    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int): super(context, attrs, defStyleAttr, defStyleRes) {
        // 获取自定义属性
        val typeArray = context.obtainStyledAttributes(attrs, R.styleable.MyTextView)
        typeArray.apply {
            try {
                mText = typeArray.getString(R.styleable.MyTextView_text)
                mTextColor = typeArray.getColor(R.styleable.MyTextView_textColor, mTextColor)
                // 15 15px 15sp
                mTextSize = typeArray.getDimensionPixelSize(R.styleable.MyTextView_textSize, sp2px(mTextSize))

                mPaint = Paint().apply {
                    isAntiAlias = true  //抗锯齿，会清晰一点
                    textSize = mTextSize.toFloat()
                    color = mTextColor
                }
            } finally {
                recycle()
            }
        }
    }

    private fun sp2px(sp: Int): Int {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp.toFloat(), resources.displayMetrics).toInt()
    }

    /**
     * 自定义View的测量方法
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        // 布局的宽高都是由这个方法指定
        // 指定控件的宽高，需要测量
        // 获取宽高的模式

        /*
            MeasureSpec包含两个信息：mode和size，模式与大小，
                mode：前2位，size：后30位
         */

        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        /*
         *  MeasureSpec.AT_MOST: 在布局忠指定了wrap_content
         *  MeasureSpec.EXACTLY: 在布局中制定了确切的值 100dp、match_parent
         *  MeasureSpec.UNSPECIFIED: 尽可能的大，很少能用到，ListView、ScrollView
         */

        mPaint.getTextBounds(mText, 0, mText?.length ?: 0, mRect) // 获取文本的 rect

        // 1.确定的值，这个时候不需要计算，给多少是多少
        var width = MeasureSpec.getSize(widthMeasureSpec)

        // 2.给的是wrap_content 需要计算
        if (widthMode == MeasureSpec.AT_MOST) {
            // 计算的宽度 与 字体的长度有关 与 字体的大小有关  用画笔来测量 Paint
            width = mRect.width() + paddingStart + paddingEnd
        }

        var height = MeasureSpec.getSize(heightMeasureSpec)

        if (heightMode == MeasureSpec.AT_MOST) {
            height = mRect.height() + paddingTop + paddingBottom
        }

        setMeasuredDimension(width, height)

    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
//        // 画文本
//        canvas.drawText()
//        // 画弧
//        canvas.drawArc()
//        // 画线
//        canvas.drawLine()

        // x 就是开始的位置
        // y 就是基线 base line 求值？   已知 height / 2

        // dy 代表的是   高度的一半到 baseLine 的距离
        // dy 怎么算？  top为负值、bottom为正值    (-top + bottom) / 2 - bottom   ->  化简：- (top + bottom) / 2  结果为正值
        val fontMetrics = mPaint.getFontMetricsInt()
        val dy =  - ( fontMetrics.top + fontMetrics.bottom ) / 2
        val baseLine = height.toFloat() / 2.0f + dy
        val x = paddingStart
        canvas.drawText(mText ?: "6666",x.toFloat(), baseLine, mPaint)
    }

    /**
     * 这里跟用户交互的，手指触摸等等
     * @param event 事件分发，拦截
     */
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_UP -> {
                // 手指抬起
            }
            MotionEvent.ACTION_DOWN -> {
                // 手指按下
            }
            MotionEvent.ACTION_MOVE -> {
                // 手指移动
            }
            else -> {}
        }


        return super.onTouchEvent(event)
    }

    override fun performClick(): Boolean {
        return super.performClick()
    }
}